package com.xuetang9.fujian.net.client;

import com.xuetang9.fujian.net.reponse.AbstractResponseHandler;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Objects;

/**
 * @describe:
 * @author:fujian
 * @date:2021/6/13
 * @Version: V1.0
 * @Package: com.xuetang9.fujian.net.client
 */
@SuppressWarnings("all")
public class Client implements Runnable{

    private Socket socket;

    private ObjectInputStream objectInputStream;

    private ObjectOutputStream objectOutputStream;

    private Integer serverPort;

    private String serverIP;

    private static Client client;

    public static final int RUNNING = 1;

    public static final int CLOSE = 2;

    private int statues;

    private Client(String serverIP,Integer serverPort){
        this.serverIP = serverIP;
        this.serverPort = serverPort;
        statues = RUNNING;
    }

    public static Client creatClient(String serverIP, Integer serverPort){
        if (Objects.isNull(client)){
            client = new Client(serverIP,serverPort);
        }
        return client;
    }

    public void start(){
        new Thread(this).start();
    }

    @Override
    public void run() {
        try {
            socket = new Socket(serverIP,serverPort);
            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            objectInputStream = new ObjectInputStream(socket.getInputStream());
            Object data = null;
            while (getStatues() == RUNNING && (data = objectInputStream.readObject()) != null ){
                if (data instanceof HashMap){
                    // deal with
                    handleMessage((HashMap<String,Object>)data);
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void handleMessage(HashMap<String, Object> message) {
        if (Objects.isNull(message.get("handlerClass"))){
            System.out.println("handlerClass is null");
            return;
        }
        String  handlerClass = message.get("handlerClass").toString();
        try {
            Object handlerObject = Class.forName(handlerClass).newInstance();
            if (handlerObject instanceof AbstractResponseHandler){
                AbstractResponseHandler handler = (AbstractResponseHandler) handlerObject;
                message.remove("handlerClass");
                handler.handleRequest(message,this);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(HashMap<String,Object> message){
        try {
            objectOutputStream.writeObject(message);
            objectOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1",9999);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());

            HashMap<String,Object> message = new HashMap<>();
            message.put("handlerClass","com.xuetang9.fujian.net.request.ClientExitRequestHandler");
            message.put("exit",true);
            objectOutputStream.writeObject(message);
            objectOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setStatues(int statues) {
        this.statues = statues;
    }

    public int getStatues() {
        return statues;
    }
}
